﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace NetDh.Lib.Extensions
{
    public static class CommonExtensions
    {
        #region Exception Msg
        /// <summary>
        /// 获取完整的异常信息，包含InnerException。
        /// </summary>
        /// <param name="needLogDateTime">是否记录当前时间</param>
        public static string GetAllErrorMsg(this Exception e, bool needLogDateTime = false)
        {
            StringBuilder sb = new StringBuilder();
            Exception ex = e;
            do
            {
                sb.AppendLine(ex.GetErrorMsg());
                ex = ex.InnerException;
            }
            while (ex != null);
            var dtMsg = needLogDateTime ? DateTime.Now.ToStringX() + Environment.NewLine : string.Empty;
            return dtMsg + sb.ToString();
        }
        /// <summary>
        /// 获取当前Exception异常信息
        /// </summary>
        /// <param name="needLogDateTime">是否记录当前时间</param>
        public static string GetErrorMsg(this Exception e, bool needLogDateTime = false)
        {
            var dtMsg = needLogDateTime ? DateTime.Now.ToStringX() + Environment.NewLine : string.Empty;
            return dtMsg + $"【ErrorMsg】:{e.Message}{Environment.NewLine}【StackTrace】:{e.StackTrace}";
        }
        #endregion

        #region DateTime Timestamp
        /// <summary>
        /// DateTime转为 yyyy-MM-dd HH:mm:ss/yyyy-MM-dd HH:mm:ss.fff 字符串格式
        /// </summary>
        /// <param name="includeMs">是否包含毫秒.fff</param>
        public static string ToStringX(this DateTime time, bool includeMs = false)
        {
            if (includeMs)
                return time.ToString("yyyy-MM-dd HH:mm:ss.fff");
            return time.ToString("yyyy-MM-dd HH:mm:ss");
        }
        public static int GetTimestamp(this DateTime time)
        {
            DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
            return (int)(time - startTime).TotalSeconds;
        }
        public static DateTime GetDateTimeFromTimestamp(this int timestamp)
        {
            DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
            long lTime = Int64.Parse(timestamp.ToString() + "0000000");
            TimeSpan toNow = new TimeSpan(lTime);
            return dtStart.Add(toNow);
        }
        #endregion

        #region Http
        public static string GetHeaderValue(this HttpRequestMessage requestMessage, string key)
        {
            IEnumerable<string> tokenArr = null;
            requestMessage.Headers.TryGetValues(key, out tokenArr);
            if (tokenArr != null && tokenArr.Count() > 0)
            {
                return tokenArr.FirstOrDefault();
            }
            return string.Empty;
        }

        public static bool IsAjaxRequest(this HttpRequest request)
        {
            return request["X-Requested-With"] == "XMLHttpRequest" || (request.Headers != null && request.Headers["X-Requested-With"] == "XMLHttpRequest");
        }
        /// <summary>
        /// 获取http请求的客户端源ip
        /// </summary>
        public static string GetClientIp(this HttpRequest request)
        {
            //如果有cdn,则HTTP_X_FORWARDED_FOR也可取到源请求ip
            var ip = request.ServerVariables.Get("HTTP_X_FORWARDED_FOR") ?? request.ServerVariables.Get("REMOTE_ADDR") ?? request.UserHostAddress;
            return ip;
        }
        /// <summary>
        /// 获取http请求的客户端源ip
        /// </summary>
        public static string GetClientIp(this HttpRequestBase request)
        {
            //如果有cdn,则HTTP_X_FORWARDED_FOR也可取到源请求ip
            var ip = request.ServerVariables.Get("HTTP_X_FORWARDED_FOR") ?? request.ServerVariables.Get("REMOTE_ADDR") ?? request.UserHostAddress;
            return ip;
        }
        #endregion
    }
}
